/*
 * IMP alloc manager function header file.
 *
 * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd
 * Author: Aeolus <weiqing.yan@ingenic.com>
 */

#ifndef __ALLOC_MANAGER_H__
#define __ALLOC_MANAGER_H__

#include <stdlib.h>
#include <stdint.h>

#include <system/imp_alloc.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

struct Alloc;
typedef struct Alloc Alloc;
struct AllocInfo;
typedef struct AllocInfo AllocInfo;

typedef struct {
	char method[MAX_NAME_LEN];
	uint32_t vaddr;
	uint32_t paddr;
	int length;
	int   (*init)(Alloc *alloc);
	uint32_t (*get_paddr)(uint32_t vaddr);
	uint32_t (*get_vaddr)(uint32_t paddr);
	int (*flush_cache)(uint32_t vaddr, size_t size, uint32_t dir);
} MemAlloc;

typedef struct {
	char method[MAX_NAME_LEN];
	int   (*init)(void *base, int size);
	void* (*memalloc)(int size);
	void  (*memfree)(void *ptr);
	void  (*dump)();
	void  (*dump_to_file)();
} MemManager;

struct AllocInfo{
	AllocInfo *n_info;
	char owner[MAX_NAME_LEN];
	uint32_t vaddr;
	uint32_t paddr;
	int length;
	int ref_cnt;
	IMPMemAttr mem_attr;
};

typedef enum {
	ALLOC_NOT_INITIALIZED,
	ALLOC_ALREADY_INITIALIZED,
} AllocInitStatus;

int allocInit(Alloc *alloc);
void *allocMem(Alloc *alloc, int size, char *owner);
void *spAllocMem(Alloc *alloc, void *ptr);
void freeMem(Alloc *alloc, void *ptr);
IMPMemAttr getMemAttr(Alloc *alloc, void *ptr);
int setMemAttr(Alloc *alloc, void *ptr, IMPMemAttr attr);
int dumpMemStatus(Alloc *alloc);
int dumpMemToFile(Alloc *alloc);

struct Alloc {
	AllocInfo info;
	AllocInitStatus init_status;
	MemAlloc mem_alloc;
	MemManager mem_manager;
	void* (*alloc_mem)(Alloc *alloc, int size, char *owner);
	void* (*sp_alloc_mem)(Alloc *alloc, void *ptr);
	void  (*free_mem)(Alloc *alloc, void *ptr);
	AllocInfo* (*getAllocInfo)(Alloc *alloc, void *ptr);
	IMPMemAttr (*get_mem_attr)(Alloc *alloc, void *ptr);
	int (*set_mem_attr)(Alloc *alloc, void *ptr, IMPMemAttr attr);
	int (*dump_mem_status)(Alloc *alloc);
	int (*dump_mem_to_file)(Alloc *alloc);
};

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __ALLOC_MANAGER_H__ */
